﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using ScaffoldIt.Configuration;
using EnvDTE;
using EnvDTE80;
using Microsoft.VisualStudio.TextTemplating;
using System.Globalization;

namespace ScaffoldIt
{
    static class ConfigHelpers
    {
        public static bool HasConfig()
        {
            var DTE = (EnvDTE80.DTE2)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(Microsoft.VisualStudio.Shell.Interop.SDTE));

            return DTE.ScaffoldingConfigFile() != null;
        }

        public static string ScaffoldingConfigFile(this EnvDTE80.DTE2 DTE)
        {
            if (DTE == null || DTE.Solution == null || string.IsNullOrEmpty(DTE.Solution.FileName)) return null;

            var solutionFolder = Path.GetDirectoryName(DTE.Solution.FileName);
            var path = Path.Combine(solutionFolder, "scaffolding.xml");
            if (File.Exists(path))
            {
                return path;
            }

            path = Path.Combine(solutionFolder, "scaffolding.config");
            if (File.Exists(path))
            {
                return path;
            }

            return null;
        }

        public static ScaffoldItConfig GetConfig(this EnvDTE80.DTE2 DTE)
        {
            var cfgfile = DTE.ScaffoldingConfigFile();
            if (cfgfile != null)
            {
                return ScaffoldItConfig.Load(cfgfile);
            }

            return null;
        }

        public static Project GetScaffoldItItem(this EnvDTE80.DTE2 DTE)
        {
            foreach (Project project in DTE.Solution.Projects)
            {
                if (project.Kind == ProjectKinds.vsProjectKindSolutionFolder)
                {
                    var name = project.Name.ToLower();
                    if (name == "scaffold it" || name == "scaffoldit")
                    {
                        return project;
                    }
                }
            }

            return null;
        }

        public static Project GetOrCreateScaffoldItItem(this EnvDTE80.DTE2 DTE)
        {
            Solution2 sol = (Solution2)DTE.Solution;
            var item = DTE.GetScaffoldItItem();

            if (item == null)
            {
                item = sol.AddSolutionFolder("Scaffold it");
            }

            var confFile = DTE.ScaffoldingConfigFile();
            if (confFile != null)
            {
                var confitem = DTE.Solution.FindProjectItem(confFile);
                if (confitem == null) 
                    confitem = item.ProjectItems.AddFromFile(confFile);
            }

            return item;
        }

        public static Project GetProject(this EnvDTE80.DTE2 DTE, string name)
        {
            foreach (Project prj in DTE.Solution.Projects)
            {
                if (prj.Kind == ProjectKinds.vsProjectKindSolutionFolder)
                {
                    var res = DTE.GetProject(prj.ProjectItems, name);
                    if (res != null) return res;
                }
                else if (string.Compare(prj.Name, name, true) == 0)
                {
                    return prj;
                }
            }

            return null;
        }

        private static Project GetProject(this EnvDTE80.DTE2 DTE, ProjectItems items, string name)
        {
            foreach (ProjectItem item in items)
            {
                if (item.Kind == Constants.vsProjectItemKindSolutionItems)
                {
                    var prj = item.Object as Project;
                    if ((prj != null) && (string.Compare(prj.Name, name, true) == 0))
                    {
                        return prj;
                    }
                }
                else if (item.Kind == Constants.vsProjectItemKindVirtualFolder)
                {
                    var res = DTE.GetProject(item.ProjectItems, name);
                    if (res != null) return res;
                }
            }

            return null;
        }

        public static string ToNamespace(this string txt)
        {
            var res = txt.Replace("\\", ".");
            res = res.Replace(" ", "_");
            res = res.RemoveDiacritics();
            return res;
        }

        /// <summary>
        /// Remplacement des caractères accentués
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string RemoveDiacritics(this string s)
        {
            string normalizedString = s.Normalize(NormalizationForm.FormD);
            StringBuilder stringBuilder = new StringBuilder();

            foreach (char c in normalizedString)
            {
                if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
                    stringBuilder.Append(c);
            }

            return stringBuilder.ToString();
        }
    }
}
